﻿// (c) Copyright slimCODE Software Inc. - www.slimcode.com
// This source is subject to the Microsoft Public License (Ms-PL).
// Please see http://go.microsoft.com/fwlink/?LinkID=131993 for details.
// All other rights reserved.

using System;
using System.Collections.Generic;
using System.Windows.Forms;
using System.Drawing;
using Microsoft.WindowsCE.Forms;
using SlimCode.Windows.Forms.Mobile;
using SlimCode.Windows.Controls.Mobile;

namespace SlimCode.SlimPasswords
{
  static class Program
  {
    private static Settings mg_settings = new Settings();

    [MTAThread]
    static void Main()
    {
      string settingsFilename = System.IO.Path.Combine(
        Environment.GetFolderPath( Environment.SpecialFolder.ApplicationData ),
        @"slimPASSWORDS\Settings.xml" );

      mg_settings.Load( settingsFilename );

      ApplicationForm appForm = new ApplicationForm();

      appForm.AutoAdjustWithWorkingArea = true;
      appForm.Icon = ImageCache.ApplicationIcon;
      appForm.MinimizeBox = true;

      appForm.ShowingScreen += new ScreenChangeEventHandler( AppForm_ShowingScreen );
      appForm.HidingScreen += new ScreenChangeEventHandler( AppForm_HidingScreen );

      // The "search password" screen is at the bottom of the stack.
      appForm.ShowScreen( new SearchPasswordScreen() );

      // On load, we suggest opening the last password store.
      SelectStoreScreen screen = new SelectStoreScreen();

      screen.StoreFilename = Program.Settings.LastStore;
      appForm.ShowScreen( screen );

      Application.Run( appForm );

      mg_settings.Save( settingsFilename );
    }

    internal static PasswordStore ActiveStore { get; set; }

    internal static Settings Settings 
    {
      get { return mg_settings; }
    }

    internal static void ToggleInputPanelIf( InputPanel inputPanel, bool enable )
    {
      if( !enable )
      {
        inputPanel.Enabled = false;
      }
      else if( !Microsoft.WindowsMobile.Status.SystemState.KeyboardPresent
        || ( Microsoft.WindowsMobile.Status.SystemState.DisplayRotation == 0 ) )
      {
        // TODO: I'm annoying blackberry-like devices with permanent keyboards below screen.
        inputPanel.Enabled = true;
      }
    }

    internal static void VisitTwitter()
    {
      try
      {
        System.Diagnostics.Process.Start( @"http://twitter.com/slimcode", string.Empty );
      }
      catch { }
    }

    internal static void ContactSupport()
    {
      try
      {
        System.Diagnostics.Process.Start( @"mailto:support@slimcode.com?subject=slimPASSWORDS%20support", string.Empty );
      }
      catch { }
    }

    internal static bool LoadStore( string fileName, string password )
    {
      PasswordStore store = new PasswordStore();

      Cursor current = Cursor.Current;
      Cursor.Current = Cursors.WaitCursor;

      try
      {
        store.Load( fileName, password );

        Program.ActiveStore = store;
        Program.Settings.LastStore = fileName;

        return true;
      }
      catch( ApplicationException except )
      {
        MessageBox.Show(
          except.Message,
          "Error",
          MessageBoxButtons.OK,
          MessageBoxIcon.Hand,
          MessageBoxDefaultButton.Button1 );
      }
      catch( Exception except )
      {
        MessageBox.Show(
          "An unexpected error occurred: " + except.Message,
          "Error",
          MessageBoxButtons.OK,
          MessageBoxIcon.Hand,
          MessageBoxDefaultButton.Button1 );
      }
      finally
      {
        Cursor.Current = current;
      }

      return false;
    }

    internal static bool SaveStore( PasswordStore store, IScreenHost host )
    {
      // This should be in a method.
      string fileName = store.FileName;
      string password = store.MainPassword;

      if( string.IsNullOrEmpty( fileName ) )
        return false;

      Cursor current = Cursor.Current;
      Cursor.Current = Cursors.WaitCursor;

      try
      {
        store.Save( fileName, password );

        return true;
      }
      catch( ApplicationException except )
      {
        MessageBox.Show(
          except.Message,
          "Error",
          MessageBoxButtons.OK,
          MessageBoxIcon.Hand,
          MessageBoxDefaultButton.Button1 );
      }
      catch( Exception except )
      {
        MessageBox.Show(
          "An unexpected error occurred: " + except.Message,
          "Error",
          MessageBoxButtons.OK,
          MessageBoxIcon.Hand,
          MessageBoxDefaultButton.Button1 );
      }
      finally
      {
        Cursor.Current = current;
      }

      return false;
    }

    private static void AppForm_ShowingScreen( object sender, ScreenChangeEventArgs args )
    {
      Program.UpdateTemplates( args.Screen.Control.Controls );

      ApplicationForm appForm = sender as ApplicationForm;

      // Changing MinimizeBox from true to false may cause the form to loose focus.
      bool previous = appForm.MinimizeBox;
      appForm.MinimizeBox = ( args.ScreenCount == 1 );

      if( previous != appForm.MinimizeBox )
      {
        appForm.Activate();
      }
    }

    private static void AppForm_HidingScreen( object sender, ScreenChangeEventArgs args )
    {
      ApplicationForm appForm = sender as ApplicationForm;

      if( args.ScreenCount == 0 )
      {
        appForm.Close();
      }
      else
      {
        // Changing MinimizeBox from true to false may cause the form to loose focus.
        bool previous = appForm.MinimizeBox;
        appForm.MinimizeBox = ( args.ScreenCount == 1 );

        if( previous != appForm.MinimizeBox )
        {
          appForm.Activate();
        }
      }
    }

    internal static void UpdateTemplates( Control.ControlCollection controls )
    {
      foreach( Control control in controls )
      {
        TemplatedButton buttonControl = control as TemplatedButton;

        if( buttonControl != null )
        {
          buttonControl.BackColor = Color.FromArgb( 0x001122 );
          buttonControl.ForeColor = Color.White;

          buttonControl.TransparencyKey = Color.Fuchsia;

          buttonControl.Template = ImageCache.Button;
          buttonControl.PressedTemplate = ImageCache.ButtonPressed;
          buttonControl.SelectedTemplate = ImageCache.ButtonFocused;

          buttonControl.TemplateBottomMargin =
          buttonControl.TemplateLeftMargin =
          buttonControl.TemplateRightMargin =
          buttonControl.TemplateTopMargin = 6;
        }
        else
        {
          TemplatedList listControl = control as TemplatedList;

          if( listControl != null )
          {
            listControl.BackColor = Color.FromArgb( 0x001122 );
            listControl.ForeColor = Color.White;

            listControl.TransparencyKey = Color.Fuchsia;

            listControl.Template = ImageCache.Bubble;
            listControl.FocusedTemplate = ImageCache.BubbleFocused;
            listControl.PressedTemplate = ImageCache.BubblePressed;
            listControl.SelectedTemplate = ImageCache.BubbleSelected;

            listControl.TemplateBottomMargin =
            listControl.TemplateLeftMargin =
            listControl.TemplateRightMargin =
            listControl.TemplateTopMargin = 3;

            listControl.ScrollThumbPattern = ImageCache.ScrollThumb;
            listControl.Momentum = 50;
          }
        }
      }
    }
  }
}